package com.rong.juc_test.juc_base.sync;

/**
 * 多线程编程：
 * 实例一： 对一个初始值是0的变量 存在不同线程对其进行加一减一操作，且变量为0时+1；为1时-1
 */
public class ThreadDemo1 {
    public static void main(String[] args) {
        // 创建多个线程 调用资源类不同的操作方法
        Share share = new Share();
        new Thread(() -> {
            for(int i = 0; i < 10; i++){
                try {
                    share.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"AA").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++){
                try {
                    share.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"BB").start();
        new Thread(() -> {
            for(int i = 0; i < 10; i++){
                try {
                    share.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"CC").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++){
                try {
                    share.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"DD").start();
    }
}

// 第一步：创建资源类
class Share {
    // 初始值
    private int number = 0;

    // +1方法
    public synchronized void incr() throws InterruptedException {
        while (number != 0){ // 将if换成while避免虚假唤醒的情况，即每次唤醒都会再次判断
            // 若number为0则等待
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName() +  " => " + number);
        this.notifyAll();// 通知其他线程
    }

    // -1方法
    public synchronized void decr() throws InterruptedException {
        while (number != 1){
//            number为1则等待
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName() +  " => " + number);
        this.notifyAll(); //通知其他线程
    }
}
